package com.xccvt.reflection;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class       Main {
    public static void main(String[] args) {
        test2();
    }
    public static void test2() {
        try {
            Class<?> personClass = Class.forName("com.xccvt.reflection.Person");

            System.out.println("Class对象: " + personClass);
            System.out.println("Class对象名字: " + personClass.getName());
            Constructor<?> constructor = personClass.getConstructor(String.class, int.class, String.class);
            Person o = (Person) constructor.newInstance("张三", 25, "zhangsan@example.com");

            o.setAge(30);
            o.setEmail("lisi@example.com");
            System.out.println("实例: " + o);
            System.out.println("实例属性: "+ o.getName());
            System.out.println("构造子: " + constructor);

            Field name = personClass.getDeclaredField("name");
            name.setAccessible(true);
            name.set(o, "王五");
            System.out.println("实例属性: " + o.getName());
            Method publicMethod = personClass.getMethod("publicMethod");
            publicMethod.invoke(o);
        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        } catch (NoSuchMethodException e) {
            throw new RuntimeException(e);
        } catch (InvocationTargetException e) {
            throw new RuntimeException(e);
        } catch (InstantiationException e) {
            throw new RuntimeException(e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        } catch (NoSuchFieldException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 反射举例
     */
    public static void test1() {

        try {
            System.out.println("=== Java反射机制示例 ===\n");

            // 1. 获取Class对象的三种方式
            System.out.println("1. 获取Class对象:");
            Class<?> personClass1 = Class.forName("com.xccvt.reflection.Person");
            Class<?> personClass2 = Person.class;
            Person personInstance = new Person();
            Class<?> personClass3 = personInstance.getClass();

            System.out.println("通过Class.forName(): " + personClass1.getName());
            System.out.println("通过类名.class: " + personClass2.getName());
            System.out.println("通过实例.getClass(): " + personClass3.getName());
            System.out.println();

            // 2. 获取构造函数并创建实例
            System.out.println("2. 使用反射创建对象:");
            Constructor<?> constructor = personClass1.getConstructor();
            Person person = (Person) constructor.newInstance();
            System.out.println("通过无参构造函数创建的对象: " + person);

            // 使用有参构造函数创建实例
            Constructor<?> paramConstructor = personClass1.getConstructor(String.class, int.class, String.class);
            Person person2 = (Person) paramConstructor.newInstance("张三", 25, "zhangsan@example.com");
            System.out.println("通过有参构造函数创建的对象: " + person2);
            System.out.println();

            // 3. 操作字段
            System.out.println("3. 使用反射操作字段:");
            Field nameField = personClass1.getDeclaredField("name");
            // 设置私有字段可访问
            nameField.setAccessible(true);
            nameField.set(person, "李四");

            Field ageField = personClass1.getDeclaredField("age");
            ageField.setAccessible(true);
            ageField.set(person, 30);

            Field emailField = personClass1.getDeclaredField("email");
            emailField.setAccessible(true);
            emailField.set(person, "lisi@example.com");

            System.out.println("通过反射设置字段后的对象: " + person);
            System.out.println("通过反射获取name字段值: " + nameField.get(person));
            System.out.println();

            // 4. 调用方法
            System.out.println("4. 使用反射调用方法:");
            // 调用公共方法
            Method publicMethod = personClass1.getMethod("publicMethod");
            System.out.print("调用publicMethod(): ");
            publicMethod.invoke(person);

            // 调用getter方法
            Method getNameMethod = personClass1.getMethod("getName");
            String name = (String) getNameMethod.invoke(person);
            System.out.println("通过反射调用getName()获取的姓名: " + name);
            System.out.println();

            // 5. 调用私有方法
            System.out.println("5. 使用反射调用私有方法:");
            Method privateMethod = personClass1.getDeclaredMethod("privateMethod");
            privateMethod.setAccessible(true);
            System.out.print("调用privateMethod(): ");
            privateMethod.invoke(person);
            System.out.println();

            // 6. 获取类信息
            System.out.println("6. 类信息:");
            System.out.println("类名: " + personClass1.getName());
            System.out.println("简单类名: " + personClass1.getSimpleName());
            System.out.println("包名: " + personClass1.getPackage().getName());

            Field[] fields = personClass1.getDeclaredFields();
            System.out.println("声明的字段数量: " + fields.length);
            for (Field field : fields) {
                System.out.println("  字段: " + field.getName() + " (类型: " + field.getType().getSimpleName() + ")");
            }

            Method[] methods = personClass1.getDeclaredMethods();
            System.out.println("声明的方法数量: " + methods.length);
            for (Method method : methods) {
                System.out.println("  方法: " + method.getName() + " (返回类型: " + method.getReturnType().getSimpleName() + ")");
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
